package secondriver.process.core;

import java.awt.image.BufferedImage;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Objects;
import java.util.function.Supplier;
import secondriver.process.core.source.Source;
import secondriver.process.core.source.SourceManager;
import secondriver.process.exception.SourceTypeNoSupportException;
import spark.utils.StringUtils;

/**
 * Author : secondriver
 * Date :  2016/1/5
 */
public class ImageEntry {

    private String source;
    private Source object;
    private String identity;
    private BufferedImage image;
    private ImageMimeType mimeType;

    private ImageEntry() {
    }

    public static ImageEntry create(String source) throws SourceTypeNoSupportException {
        ImageEntry imageEntry = new ImageEntry();
        imageEntry.source = source;
        Source s = SourceManager.getSource(source);
        if (Objects.isNull(s)) {
            throw new SourceTypeNoSupportException("Source='" + source + "' can't supported.");
        }
        imageEntry.object = s;
        imageEntry.mimeType = ImageMimeType.parseOrDefault(getExtension(source));
        imageEntry.identity = base65Url(source) + "." + imageEntry.mimeType.getFormatName();
        return imageEntry;
    }

    public void fetch() {
        try {
            this.image = object.fetch(object.convert(source));
        } catch (Exception e) {
            throw new SourceTypeNoSupportException("Source='" + source + "' can't supported .");
        }
    }

    public ImageEntry fetch(Supplier<BufferedImage> supplier) {
        this.image = supplier.get();
        return this;
    }

    public boolean isComplete() {
        return StringUtils.isNotEmpty(source)
                && StringUtils.isNotEmpty(identity)
                && Objects.nonNull(object)
                && Objects.nonNull(mimeType)
                && Objects.nonNull(image);
    }

    private static String base65Url(String value) {
        Objects.requireNonNull(value);
        return Base64.getUrlEncoder().encodeToString(value.getBytes(StandardCharsets.UTF_8));
    }

    private static String getExtension(String source) {
        if (StringUtils.isNotEmpty(source)) {
            if (source.indexOf('.') != -1 && source.lastIndexOf('.') != source.length() - 1) {
                int lastIndex = source.lastIndexOf('.');
                return source.substring(lastIndex + 1);
            }
        }
        return "";
    }

    public String getIdentity() {
        return identity;
    }

    public BufferedImage getImage() {
        return image;
    }

    public ImageMimeType getMimeType() {
        return mimeType;
    }

    public boolean isRemoteSource() {
        return object.isRemoteSource();
    }
}